﻿using System;
using System.Diagnostics;
using System.Linq;
using System.Windows.Forms;
using Microsoft.Win32.TaskScheduler;

namespace Commands.Scheduling
{
    internal static class Suspender
    {
        /// <summary>
        /// Constructor.
        /// </summary>
        static Suspender()
        {
            // Need to remove task when application exit.
            AppDomain.CurrentDomain.ProcessExit += (_, __) => { _RemoveWakeUpTask(TASK_NAME); };
        }

        public static void SuspendNow(DateTime wakeUpTime)
        {
            // Check that time has been set correctly.
            if (wakeUpTime <= DateTime.Now)
            {
                Debug.Assert(false);
                return;
            }

            _RemoveWakeUpTask(TASK_NAME);
            _WakeUpIn(wakeUpTime, TASK_NAME);
            _SuspendNow();
        }

        /// <summary>
        /// Stop computer from suspending/wakeuping.
        /// </summary>
        public static void RemoveWakeUpTask()
        {
            _RemoveWakeUpTask(TASK_NAME);
        }

        #region Private members

        private static void _SuspendNow()
        {
            System.Windows.Forms.Application.SetSuspendState(PowerState.Suspend, false, false);
        }

        /// <summary>
        /// Schedule wakeup.
        /// </summary>
        /// <param name="wakeUpTime">Time in which computer must be waked up.</param>
        private static void _WakeUpIn(DateTime wakeUpTime, string taskName)
        {
            // Get the service on the local machine
            using (TaskService ts = new TaskService())
            {
                TaskDefinition td = ts.NewTask();
                td.Triggers.Add(new TimeTrigger() { StartBoundary = wakeUpTime, Enabled = true });
                td.Actions.Add(new ShowMessageAction("Hello!", "Remote commands"));
                td.Settings.WakeToRun = true;
                ts.RootFolder.RegisterTaskDefinition(taskName, td);
            }
        }

        private static void _RemoveWakeUpTask(string name)
        {
            using (TaskService ts = new TaskService())
            {
                if(ts.RootFolder.Tasks.Any(x => x.Name == name))
                    ts.RootFolder.DeleteTask(name);
            }
        }

        private static string TASK_NAME = @"Remote commands task";

        #endregion
    }
}
